﻿using LM.Negocio.Objetos;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace LM.Repositorios
{
    public class RepositorioDeObjetosAbstrato<T> : IRepositorioCompletoDeObjetos<T>
        where T : ObjetoPersistido
    {
        public T Consulte(Guid id)
        {
            var contexto = new Contexto();
            return contexto.Set<T>().FirstOrDefault(x => x.Id == id);
            
        }

        public IList<T> Consulte(Expression<Func<T, bool>> expressao)
        {
            var contexto = new Contexto();
            return contexto.Set<T>().Where(expressao).ToList();
        }

        public IList<T> ConsulteTodos()
        {
            var contexto = new Contexto();
            return contexto.Set<T>().ToList();
        }

        public void Cadastre(T objeto)
        {
            var contexto = new Contexto();
            contexto.Set<T>().Add(objeto);
            contexto.SaveChanges();
        }

        public void Atualize(T objeto)
        {
            var contexto = new Contexto();
            var objetoCadastrado = ConsulteObjetoPersistido(objeto);
            if (objetoCadastrado != null)
            {
                objeto.Id = objetoCadastrado.Id;
                var obj = contexto.Entry(contexto.Set<T>().Single(o => o.Id == objetoCadastrado.Id));
                obj.CurrentValues.SetValues(objeto);
                contexto.SaveChanges();
            }
        }

        public void Exclua(T objeto)
        {
            var contexto = new Contexto();
            
            var objetoCadastrado = ConsulteObjetoPersistido(objeto);
            if (objetoCadastrado != null)
            {
                contexto.Set<T>().Remove(contexto.Set<T>().Single(o => o.Id == objetoCadastrado.Id));
                contexto.SaveChanges();
            }
        }

        protected virtual T ConsulteObjetoPersistido(T objeto)
        {
            var contexto = new Contexto();
            return contexto.Set<T>().FirstOrDefault(o => o.Id == objeto.Id);
        }
    }
}
